﻿
using EmperialApps.WeatherSpark.Agent;
using EmperialApps.WeatherSpark.Data;
using EmperialApps.WeatherSpark.Internal;
using EmperialApps.WeatherSpark.Resources;
using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;


namespace EmperialApps.WeatherSpark {

    /// <summary>Displays advanced settings.</summary>
    public partial class AdvancedSettingsPage : PhoneApplicationPage {

        public AdvancedSettingsPage( ) {
            typeof( AdvancedSettingsPage ).Log( "Initializing" );
            InitializeComponent( );


            typeof( SettingsPage ).Log( "- Loading tile background colors" );
            var accentBrush = Settings.GetAccentBrush( );
            var currentColor = new NamedColor( Settings.TileBackgroundColorValue, "current" );

            var colors = new List<NamedColor> {
                new NamedColor( 0, "transparent" ),
                new NamedColor( accentBrush, "accent" )
            };
            colors.AddRange( NamedColor.Values );
#if DEBUG
            colors.Remove( currentColor );
#endif
            if( !colors.Contains( currentColor ) )
                colors.Insert( 0, currentColor );

            this.TileBackground.ItemsSource = colors;
            this.TileBackground.SelectedItem = currentColor;
            this.TileBackground.SelectionChanged += this.OnTileBackgroundSelectionChanged;
            this.TileBackgroundChangeText.Visibility = Visibility.Collapsed;
        }


        protected override void OnNavigatedTo( NavigationEventArgs e ) {
            base.OnNavigatedTo( e );

            this.EnsureCurrentSettings( fallback: true );

            LocationSettings settings = Settings.Current;
            settings.UpdateTile( this.TileProgress, TileUpdateReason.Refresh );
            if( settings.Tile == ForecastDisplayMode.None ) {
                typeof( SettingsPage ).Log( "Leaving after tile unpinned" );
                this.NavigationService.GoBack( );
                return;
            }


            this.EnableWideTileButton.IsChecked = settings.EnableWideTile;

            if( this.TilePreview.Child == null ) {
                Forecast forecast;
                Exception error;
                if( settings.Location.TryLoadForecast( typeof( SettingsPage ), settings.GetIndex( ), out forecast, out error ) )
                    this.DisplayForecast( settings, forecast );
                else if( error != null )
                    error.Report( Localized.ErrorSource.Loading );
            }
        }


        #region Private Members

        private void DisplayForecast( LocationSettings settings, Forecast forecast ) {
            var tile = (TileImageBase)this.TilePreview.Child;
            if( forecast == null && tile != null )
                forecast = tile.Forecast;

            if( forecast == null )
                return;

            string pathModifier = settings.EnableWideTile ? SharedStorage.WideTileImagePathModifier : null;
            if( tile != null && tile.PathModifier == pathModifier )
                tile.BackgroundColor = Display.ToColor( Settings.TileBackgroundColorValue );
            else
                tile = SharedStorage.CreateTileImage( pathModifier, settings.GetTileTitle( ), settings.Units, settings.Tile, forecast, Settings.TileBackgroundColorValue );

            this.TilePreview.Child = tile;
        }


        private void OnEnableWideTileButtonClicked( object sender, RoutedEventArgs e ) {
            bool displayWide = this.EnableWideTileButton.IsChecked == true;

            LocationSettings settings = Settings.Current;
            if( settings.EnableWideTile != displayWide ) {
                settings.EnableWideTile = displayWide;

                this.DisplayForecast( settings, null );
                settings.RemoveTile( );
                settings.UpdateTile( this.TileProgress, TileUpdateReason.CreateTile );
            }
        }

        private void OnTileBackgroundSelectionChanged( object sender, SelectionChangedEventArgs e ) {
            if( this.TileBackground.SelectedItem == null )
                return;

            var selection = (NamedColor)this.TileBackground.SelectedItem;
            uint selectedColorValue = Display.FromColor( selection.Color );
            if( Settings.TileBackgroundColorValue != selectedColorValue ) {
                Settings.TileBackgroundColorValue = selectedColorValue;

                this.TileBackgroundChangeText.Visibility = Visibility.Visible;
                this.DisplayForecast( Settings.Current, null );
            }
        }


        private struct NamedColor : IEquatable<NamedColor> {
            // http://www.creepyed.com/2012/11/windows-phone-8-theme-colors-hex-rgb/
            public static readonly NamedColor[] Values = new[] {
                new NamedColor( 0xFFA4C400, "lime" ),
                new NamedColor( 0xFF60A917, "green" ),
                new NamedColor( 0xFF008A00, "emerald" ),
                new NamedColor( 0xFF00ABA9, "teal" ),
                new NamedColor( 0xFF1BA1E2, "cyan" ),
                new NamedColor( 0xFF0050EF, "cobalt" ),
                new NamedColor( 0xFF6A00FF, "indigo" ),
                new NamedColor( 0xFFAA00FF, "violet" ),
                new NamedColor( 0xFFF472D0, "pink" ),
                new NamedColor( 0xFFD80073, "magenta" ),
                new NamedColor( 0xFFA20025, "crimson" ),
                new NamedColor( 0xFFE51400, "red" ),
                new NamedColor( 0xFFFA6800, "orange" ),
                new NamedColor( 0xFFF0A30A, "amber" ),
                new NamedColor( 0xFFE3C800, "yellow" ),
                new NamedColor( 0xFF825A2C, "brown" ),
                new NamedColor( 0xFF6D8764, "olive" ),
                new NamedColor( 0xFF647687, "steel" ),
                new NamedColor( 0xFF76608A, "mauve" ),
                new NamedColor( 0xFF87794E, "taupe" ),
            };

            private readonly SolidColorBrush _brush;
            private readonly string _name;

            public NamedColor( SolidColorBrush brush, string id ) {
                this._name = AppResources.ResourceManager.GetString( "AdvancedSettingsPage_TileBackground_Color_" + id ) ?? id;
                this._brush = brush;
            }

            public NamedColor( uint colorValue, string name )
                : this( new SolidColorBrush( Display.ToColor( colorValue ) ), name ) { }

            public string Name { get { return this._name; } }
            public Brush Brush { get { return this._brush; } }
            public Color Color { get { return this._brush.Color; } }

            public override string ToString( ) { return this.Name; }
            public override int GetHashCode( ) { return this.Color.GetHashCode( ); }
            public bool Equals( NamedColor other ) { return this.Color.Equals( other.Color ); }
            public override bool Equals( object obj ) { return obj is NamedColor && this.Equals( (NamedColor)obj ); }
        }

        #endregion

    }

}
